extends Node2D

export(PackedScene) var tone_player

var TONE_DIR = "res://Audio/piano_keys_v2/"
var TONE_FORMAT = '.ogg'
var MAX_CHORDS_SIZE = 5
var MAX_MAIN_TONES_SIZE = 10

var tone_order = ['c','d','e','f','g','a','b']
var tone_grade = ['3','4','5']
var music = [4,5,3,6,2,5,1]

var tones = PoolStringArray()
var chords = []
var main_tones = []
var current_chord = []

var chord_timer :Timer = null # 节奏
var main_tone_timer :Timer = null

var playing = false

func _ready():
	randomize()
	# gather tones
	for x in tone_grade:
		for y in tone_order:
			tones.push_back("%s%s" % [y, x])
	# init timer
	chord_timer = $ChordTimer
	chord_timer.connect("timeout", self, "get_and_play_chord")
	
	
	main_tone_timer = $MainToneTimer
	main_tone_timer.connect("timeout", self, "get_and_play_main_tone")
#	main_tone_timer.wait_time = chord_timer.wait_time / 2
	

func make_single_tone(idx :int):
	var streamPlayer = tone_player.instance()
	streamPlayer.tone_code = tones[idx]
	streamPlayer.tone_idx = idx
	streamPlayer.stream = load("%s%s%s" % [TONE_DIR, tones[idx], TONE_FORMAT])	
	add_child(streamPlayer)
	streamPlayer.connect("finished", self, "on_StreamPlayer_finished", [streamPlayer])
	return streamPlayer
	
func on_StreamPlayer_finished(player):
	call_deferred("remove_stream_player", player)

func remove_stream_player(player :AudioStreamPlayer):
	player.queue_free()

func gen_main_tone():
	if main_tones.size() > MAX_MAIN_TONES_SIZE:
		return
	var idx = random_idx()
	main_tones.append(make_single_tone(idx))

func make_chord(idx :int) -> Array:
	var chord = []
	for i in range(3):
		chord.append(make_single_tone(idx + 2 * i))
	return chord
	
func set_current_chord(chord :Array):
	current_chord.clear()
	for i in range(chord.size()):
		current_chord.append(chord[i].tone_idx)
	
func play_chord(chord :Array) -> void:
	set_current_chord(chord)
	print(current_chord)
	var player :AudioStreamPlayer = chord.pop_front()
	while player:
		player.play()
		player = chord.pop_front()

func random_idx() -> int:
	var idx = randi() % (tones.size() - 4)
	return idx

func gen_chords(idx := -1) -> void:
	if chords.size() >= MAX_CHORDS_SIZE:
		return
	idx = random_idx() if idx == -1 else idx
	var chord = make_chord(idx)
	chords.append(chord)
	

func get_and_play_chord():
	var chord = chords.pop_front()
	if chord:
		play_chord(chord)

func get_tone_not_in_current_chord():
	var tone = null
	for i in range(main_tones.size()):
		tone = main_tones[i]
		if not current_chord.has(tone.tone_idx):
			main_tones.pop_at(i)
			break
	return tone
	

func get_and_play_main_tone():
	var main_tone = get_tone_not_in_current_chord()
	if main_tone:
		print(main_tone.tone_idx)
		main_tone.play()

func play():
	chord_timer.start()
	main_tone_timer.start()
	playing = true

func stop():
	chord_timer.stop()
	main_tone_timer.stop()
	playing = false

func play_music(tones :Array):
	if chords.size() < MAX_CHORDS_SIZE:
		var idx = tones.pop_front()
		tones.append(idx)
		gen_chords(idx - 1)

func _process(delta):
#	gen_chords()
	play_music(music)
	gen_main_tone()

func _input(event):
	if event is InputEventMouseButton:
		if event.button_index == BUTTON_LEFT and event.is_pressed():
			if playing:
				stop()
			else:
				play()

